#include	"utils.h"
#include	<ctime>
#include	<cstring>

#if defined(_WIN32)
#	include	<Windows.h>
#	include	<io.h>
#	include	<direct.h>
#else
#	include	<unistd.h>
#	include	<sys/stat.h>
#	include	<uuid/uuid.h>
#endif

double Tick() {
#if defined(_WIN32)
	static bool bInited = false;
	static double dFreq = 0;

	if (!bInited) {
		LARGE_INTEGER iPerfFreq;
		if (QueryPerformanceFrequency(&iPerfFreq)) {
			dFreq = 1.0 / iPerfFreq.QuadPart;
		}
		else {
			dFreq = 0;
		}
		bInited = true;
	}

	LARGE_INTEGER iCounter;
	if (!QueryPerformanceCounter(&iCounter)) return 0;
	return ((double)iCounter.QuadPart * dFreq * 1000);
#else
	struct timespec iClock;
	clock_gettime(CLOCK_MONOTONIC, &iClock);
	return iClock.tv_sec * 1000.0 + iClock.tv_nsec / 1000000.0;
#endif
}

std::string CreateID() {
	char		pHex[64];

#if defined(_WIN32)
	GUID		iGuid;
	uint32_t	pData[4];


	::CoInitialize(NULL);
	::CoCreateGuid(&iGuid);
	::CoUninitialize();
	::memcpy(pData, &iGuid, 16);

	_snprintf_s(pHex, 64, "%08X%08X%08X%08X", pData[0], pData[1], pData[2], pData[3]);
#else
	uuid_t		iUUID;
	uint32_t	pData[4];

	uuid_generate(iUUID);
	::memcpy(pData, iUUID, 16);

	snprintf(pHex, 64, "%08X%08X%08X%08X", pData[0], pData[1], pData[2], pData[3]);
#endif

	return std::string(pHex);
}

bool Exists(const char * sPath) {
#if defined(_WIN32)
	return _access(sPath, 0) == 0;
#else
	return access(sPath, 0) == 0;
#endif
}

void MakeDir(const char * sPath) {
#if defined(_WIN32)
	_mkdir(sPath);
#else
	mkdir(sPath, 755);
#endif
}

std::string GMTime(uint32_t nUnixTimestamp) {
	time_t nExpire = nUnixTimestamp;

#if defined(_MSC_VER)
	struct tm iGM;
	auto pGM = &iGM;
	gmtime_s(pGM, &nExpire);
#else
	auto pGM = gmtime(&nExpire);
#endif

	char pBuf[32] = { 0 };
	strftime(pBuf, 32, "%a, %d %b %Y %H:%M:%S GMT", pGM);

	return std::string(pBuf);
}